//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// KIP user-mode API library
//	
// module: wsaerr.c
// $Revision: 77 $
// $Date: 2012-01-17 22:20:34 +0400 (Вт, 17 янв 2012) $
// description:
//  Convertion of KIP-specific error codes into WIN32 error codes.

#include "project.h"
#include "err.h"

#define X(w, e) {ERROR_##w, e}
#define W(e) {WSA##e, e}

static const struct
{
	DWORD w;		 /* windows version of error */
	int e;		 /* errno version of error */
}errmap[] =
{
	W ( EWOULDBLOCK ),
	W ( EINPROGRESS ),
	W ( EALREADY ),
	W ( ENOTSOCK ),
	W ( EDESTADDRREQ ),
	W ( EMSGSIZE ),
	W ( EPROTOTYPE ),
	W ( ENOPROTOOPT ),
	W ( EPROTONOSUPPORT ),
	W ( ESOCKTNOSUPPORT ),
	W ( EOPNOTSUPP ),
	W ( EPFNOSUPPORT ),
	W ( EAFNOSUPPORT ),
	W ( EADDRINUSE ),
	W ( EADDRNOTAVAIL ),
	W ( ENETDOWN ),
	W ( ENETUNREACH ),
	W ( ENETRESET ),
	W ( ECONNABORTED ),
	W ( ECONNRESET ),
	W ( ENOBUFS ),
	W ( EISCONN ),
	W ( ENOTCONN ),
	W ( ESHUTDOWN ),
	W ( ETOOMANYREFS ),
	W ( ETIMEDOUT ),
	W ( ECONNREFUSED ),
	W ( ELOOP ),
	W ( ENAMETOOLONG ),
	W ( EHOSTDOWN ),
	W ( EHOSTUNREACH ),
	W ( ENOTEMPTY ),
	W ( EPROCLIM ),
	W ( EUSERS ),
	W ( EDQUOT ),
	W ( ESTALE ),
	W ( EREMOTE ),

	{ WSAHOST_NOT_FOUND, HOST_NOT_FOUND },
	{ WSATRY_AGAIN, TRY_AGAIN },
	{ WSANO_RECOVERY, NO_RECOVERY },
	{ WSANO_DATA, NO_DATA },
	{ WSANO_DATA, NO_ADDRESS },

	{ WSANO_DATA, ENSRNODATA },
	{ WSANO_RECOVERY, ENSRFORMERR },
	{ WSATRY_AGAIN, ENSRSERVFAIL },
	{ WSAHOST_NOT_FOUND, ENSRNOTFOUND },
	{ WSANO_RECOVERY, ENSRNOTIMP },
	{ WSANO_DATA, ENSRREFUSED },
	{ WSANO_DATA, ENSRBADQUERY },
	{ WSANO_DATA, ENSRBADNAME },
	{ WSANO_DATA, ENSRBADFAMILY },
	{ WSANO_DATA, ENSRBADRESP },
	{ WSATRY_AGAIN, ENSRCONNREFUSED },
	{ WSATRY_AGAIN, ENSRTIMEOUT },
	{ WSANO_DATA, ENSROF },
	{ WSANO_DATA, ENSRFILE },
	{ WSANO_DATA, ENSRNOMEM },
	{ WSANO_DATA, ENSRDESTRUCTION },
	{ WSANO_DATA, ENSRQUERYDOMAINTOOLONG },
	{ WSANO_DATA, ENSRCNAMELOOP },

	/* FIXME: Some of these choices are arbitrary! */
	X (INVALID_FUNCTION,		EBADRQC),
	X (FILE_NOT_FOUND,		ENOENT),
	X (PATH_NOT_FOUND,		ENOENT),
	X (TOO_MANY_OPEN_FILES,	EMFILE),
	X (ACCESS_DENIED,		EACCES),
	X (INVALID_HANDLE,		EBADF),
	X (NOT_ENOUGH_MEMORY,		ENOMEM),
	X (INVALID_DATA,		EINVAL),
	X (OUTOFMEMORY,		ENOMEM),
	X (INVALID_DRIVE,		ENODEV),
	X (NOT_SAME_DEVICE,		EXDEV),
	X (NO_MORE_FILES,		ENMFILE),
	X (WRITE_PROTECT,		EROFS),
	X (BAD_UNIT,			ENODEV),
	X (SHARING_VIOLATION,		EACCES),
	X (LOCK_VIOLATION,		EACCES),
	X (SHARING_BUFFER_EXCEEDED,	ENOLCK),
	X (HANDLE_EOF,		ENODATA),
	X (HANDLE_DISK_FULL,		ENOSPC),
	X (NOT_SUPPORTED,		ENOSYS),
	X (REM_NOT_LIST,		ENONET),
	X (DUP_NAME,			ENOTUNIQ),
	X (BAD_NETPATH,		ENOSHARE),
	X (BAD_NET_NAME,		ENOSHARE),
	X (FILE_EXISTS,		EEXIST),
	X (CANNOT_MAKE,		EPERM),
	X (INVALID_PARAMETER,		EINVAL),
	X (NO_PROC_SLOTS,		EAGAIN),
	X (BROKEN_PIPE,		EPIPE),
	X (OPEN_FAILED,		EIO),
	X (NO_MORE_SEARCH_HANDLES,	ENFILE),
	X (CALL_NOT_IMPLEMENTED,	ENOSYS),
	X (INVALID_NAME,		ENOENT),
	X (WAIT_NO_CHILDREN,		ECHILD),
	X (CHILD_NOT_COMPLETE,	EBUSY),
	X (DIR_NOT_EMPTY,		ENOTEMPTY),
	X (SIGNAL_REFUSED,		EIO),
	X (BAD_PATHNAME,		ENOENT),
	X (SIGNAL_PENDING,		EBUSY),
	X (MAX_THRDS_REACHED,		EAGAIN),
	X (BUSY,			EBUSY),
	X (ALREADY_EXISTS,		EEXIST),
	X (NO_SIGNAL_SENT,		EIO),
	X (FILENAME_EXCED_RANGE,	EINVAL),
	X (META_EXPANSION_TOO_LONG,	EINVAL),
	X (INVALID_SIGNAL_NUMBER,	EINVAL),
	X (THREAD_1_INACTIVE,		EINVAL),
	X (BAD_PIPE,			EINVAL),
	X (PIPE_BUSY,			EBUSY),
	X (NO_DATA,			EPIPE),
	X (PIPE_NOT_CONNECTED,	ECOMM),
	X (MORE_DATA,			EAGAIN),
	X (DIRECTORY,			ENOTDIR),
	X (PIPE_CONNECTED,		EBUSY),
	X (PIPE_LISTENING,		ECOMM),
	X (NO_TOKEN,			EINVAL),
	X (PROCESS_ABORTED,		EFAULT),
	X (BAD_DEVICE,		ENODEV),
	X (BAD_USERNAME,		EINVAL),
	//X (NOT_CONNECTED,		ENOLINK),
	X (OPEN_FILES,		EAGAIN),
	X (ACTIVE_CONNECTIONS,	EAGAIN),
	X (DEVICE_IN_USE,		EAGAIN),
	X (INVALID_AT_INTERRUPT_TIME,	EINTR),
	X (IO_DEVICE,			EIO),
	X (NOT_OWNER,			EPERM),
	X (END_OF_MEDIA,		ENOSPC),
	X (EOM_OVERFLOW,		ENOSPC),
	X (BEGINNING_OF_MEDIA,	ESPIPE),
	X (SETMARK_DETECTED,		ESPIPE),
	X (NO_DATA_DETECTED,		ENOSPC),
	X (POSSIBLE_DEADLOCK,		EDEADLOCK),
	X (CRC,			EIO),
	X (NEGATIVE_SEEK,		EINVAL),
	X (NOT_READY,			ENOMEDIUM),
	X (DISK_FULL,			ENOSPC),
	X (NOACCESS,			EFAULT),
	X (FILE_INVALID,		ENXIO),

	{ 0, 0}
};

DWORD get_win_error_from_errno (int code, int def)
{
	int i;
	for ( i = 0; errmap[i].w != 0; ++i){
		if (code == errmap[i].e)
		{
			return errmap[i].w;
		}
	}

	return code; //def;	/* FIXME: what's so special about EACCESS? */
}

DWORD ErrNoToWSAERROR( int err )
{
	return get_win_error_from_errno(err,ERROR_INVALID_FUNCTION);
}